home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr49 / 118_01.zip / ROFF1.BDS < prev    next >
Text File  |  1993-06-03  |  13KB  |  658 lines

  1. /* software tools format program -- C version -- Part 1
  2.  * source:  roff1.bds
  3.  * version: November 27, 1981.
  4.  */
  5.  
  6. #define VERSION  "November 27, 1981"
  7.  
  8. #include tools.h
  9. #include roff.h
  10.  
  11. main(argc, argv)
  12. int argc;
  13. char **argv;
  14. {
  15.     initst(argc, argv);
  16.     main1();
  17.     endst();
  18. }
  19.  
  20. main1()
  21. {
  22.     /* include: cpage, cparam, cout */
  23.     char *arg;
  24.     int  i, fd, nf;
  25.  
  26.     finit();
  27.  
  28.     query("usage: ROFF [-s] [+n] [-n] [-pon] [files]\n");
  29.  
  30.     putlin("Welcome to roff version 0b:,  ",SYS_TERM);
  31.     putlin(VERSION, SYS_TERM);
  32.     putlin("\n",SYS_TERM);
  33.  
  34.     /* open all files.  examine options */
  35.  
  36.     nf = 0;        /* number of open files */
  37.  
  38.     for (i = 1; (arg = getarg(i)) != EOS; i++) {
  39.  
  40.         /* -s option:  stop after each page */
  41.         if (arg [0] == '-' && tolower(arg[1]) == 's') {
  42.             stopx = YES;
  43.         }
  44.         
  45.         /* -po n option: page offset */
  46.         else if ( arg [0] == '-' &&
  47.                   tolower(arg [1]) == 'p' &&
  48.                   tolower(arg [2]) == 'o'
  49.                 ) {
  50.             set (&offset, atoi(arg + 3),
  51.                   arg [3], 0, 0, rmval - 1);
  52.         }
  53.  
  54.         /* + n option:  start printing with page n */
  55.         else if (arg [0] == '+') {
  56.             frstpg = atoi(arg + 1);
  57.         }
  58.  
  59.         /* - n option:  stop printing after page n */
  60.         else if (arg [0] == '-' && arg[1] != EOS) {
  61.             lastpg = atoi(arg + 2);
  62.         }
  63.  
  64.         /* - or filename option:  process input */
  65.         else {
  66.             if (arg [0] == '-') {
  67.                 fd = STDIN;
  68.             }
  69.             else {
  70.                 fd = open(arg, READ);
  71.             }
  72.             if (fd == ERR) {
  73.                 cant(arg);
  74.                 continue;
  75.             }
  76.             /* process one file */
  77.             doroff(fd);
  78.             nf++;
  79.             if (fd != STDIN) {
  80.                 close(fd);
  81.             }
  82.         }
  83.     } /* end of for loop */
  84.  
  85.     /* if no input files, do STDIN */
  86.     if (nf == 0) {
  87.         doroff(STDIN);
  88.     }
  89.  
  90.     /* end gracefully */
  91.     brk();
  92.     if ( plval <= 100 && 
  93.          (lineno > 0 || outp > 0)
  94.         ) {
  95.         /* flush last output */
  96.         space(HUGE);
  97.     }
  98.  
  99.     /* comment out ----- disable pagecontrol
  100.     ifdef(PAGECONTROL,
  101.         putc(PAGEJECT);
  102.         putc(NEWLINE);
  103.         )
  104.     ----- end comment out */
  105. }
  106.  
  107. /*  bold - bold-face or overstrike a line */
  108.  
  109. bold(buf, tbuf, size)
  110. char *buf, *tbuf; int size;
  111. {
  112.     int  i, j, k, k1;
  113.  
  114.     /* expand into tbuf */
  115.     k = 0;
  116.     j = 0;
  117.     for (i = 0; ; i++) {
  118.         if ( buf [i] != ' ' &&
  119.              buf [i] != TAB &&
  120.              buf [i] != BACKSPACE &&
  121.              buf [i] != STARTU &&
  122.              buf [i] != STOPU &&
  123.              buf [i] != NEWLINE
  124.            ) {
  125.         k++;
  126.         }
  127.         else {
  128.             /* over strike word */
  129.             for (k1 = k; k1 > 0; k1--) {
  130.                 tbuf [j++] = buf [i - k1];
  131.             }
  132.             for (k1 = k; k1 > 0; k1--) {
  133.                 tbuf [j++] = BACKSPACE;
  134.             }
  135.             for (k1 = k; k1 > 0; k1--) {
  136.                 tbuf [j++] = buf [i - k1];
  137.             }
  138.  
  139.             /* copy delimiter */
  140.             tbuf [j++] = buf [i];
  141.  
  142.             /* reset counter */
  143.             k = 0;
  144.             if (buf [i] == NEWLINE) {
  145.                 break;
  146.             }
  147.         }
  148.     }
  149.     tbuf [j] = EOS;
  150.     if (j >= size) {
  151.         sys_error("bold");
  152.     }
  153.  
  154.     /* copy tbuf back to buf */
  155.     scopy(tbuf, 0, buf, 0);
  156. }
  157.  
  158. /*  brk - end current filled line */
  159.  
  160. brk()
  161. {
  162.     /* include cout */
  163.  
  164.     if (outp > 0) {
  165.         outbuf [outp++] = NEWLINE;
  166.         outbuf [outp] = EOS;
  167.         put(outbuf);
  168.     }
  169.     outp = 0;
  170.     outw = 0;
  171.     outwds = 0;
  172. }
  173.  
  174. /*  center - center a line by setting tival */
  175.  
  176. center(buf)
  177. char buf [];
  178. {
  179.     /* include cparam */
  180.  
  181.     tival = max( (rmval + tival - width(buf)) / 2, 0);
  182. }
  183.  
  184. /*  command - perform formatting command */
  185.  
  186. command(buf)
  187. char *buf;
  188. {
  189.     /* include: cpage, cparam, cfiles, cnr */
  190.  
  191.     char name [MAXLINE], defn[MAXDEF];
  192.  
  193.     int   val, argtyp;    /* command line values */
  194.     int   spval;        /* temp spacing param */
  195.     int   ismacro;
  196.     int   i, j;
  197.  
  198.     /* must look for macros before expanding escapes */
  199.  
  200.     i = 1;
  201.     getwrd(buf, &i, name);
  202.     ismacro = ludef(name, defn);
  203.  
  204.     doesc(buf, name, MAXLINE);
  205.  
  206.     /*  get value of argument following command */
  207.     i = 0;
  208.     while ( buf [i] != ' ' &&
  209.             buf [i] != TAB &&
  210.             buf [i] != NEWLINE
  211.           ) {
  212.         i++;
  213.     }
  214.     /* warning:  i used below as index into buf */
  215.     val = getval(buf, &i, &argtyp);
  216.  
  217.     if (ismacro == YES) {
  218.         /* evaluate args.  push back definition */
  219.         eval(buf, defn);
  220.         return;
  221.     }
  222.  
  223.     if (lu(buf,"fi")) {
  224.         brk();
  225.         fill = YES;
  226.     }
  227.     else if (lu(buf,"br")) {
  228.         brk();
  229.     }
  230.     else if (lu(buf,"nf")) {
  231.         brk();
  232.         fill = NO;
  233.     }
  234.     else if (lu(buf,"ls")) {
  235.         set(&lsval, val, argtyp, 1, 1, HUGE);
  236.     }
  237.     else if (lu(buf,"ce")) {
  238.         brk();
  239.         set(&ceval, val, argtyp, 1, 0, HUGE);
  240.     }
  241.     else if (lu(buf,"ul")) {
  242.         cuval = 0;
  243.         set(&ulval, val, argtyp, 0, 1, HUGE);
  244.     }
  245.     else if (lu(buf,"bd")) {
  246.         set(&boval, val, argtyp, 0, 1, HUGE);
  247.     }
  248.     else if (lu(buf,"he")) {
  249.         gettl(buf, ehead, ehlim);
  250.         gettl(buf, ohead, ohlim);
  251.     }
  252.     else if (lu(buf,"fo")) {
  253.         gettl(buf, efoot, eflim);
  254.         gettl(buf, ofoot, oflim);
  255.     }
  256.     else if (lu(buf,"bp")) {
  257.         /* perform break explicitly */
  258.         brk();
  259.         if (lineno > 0) {
  260.             space(HUGE);
  261.         }
  262.         set(&curpag,val,argtyp,curpag+1,-HUGE,HUGE);
  263.         newpag = curpag;
  264.     }
  265.     else if (lu(buf,"sp")) {
  266.         set(&spval, val, argtyp, 1, 0, HUGE);
  267.         space(spval);
  268.     }
  269.     else if (lu(buf,"in")) {
  270.         brk();
  271.         set(&inval, val, argtyp, 0, 0, rmval-1);
  272.         tival = inval;
  273.     }
  274.     else if (lu(buf,"rm")) {
  275.         set(&rmval, val, argtyp, PAGEWIDTH,
  276.             tival + 1, HUGE);
  277.     }
  278.     else if (lu(buf,"ti")) {
  279.         brk();
  280.         set(&tival, val, argtyp, 0, 0, rmval);
  281.     }
  282.     else if (lu(buf,"pl")) {
  283.         set(&plval, val, argtyp, PAGELEN,
  284.             m1val+m2val+m3val+m4val+1, HUGE);
  285.         bottom = plval - m3val - m4val;
  286.     }
  287.     else if (lu(buf,"po")) {
  288.         set(&offset, val, argtyp, 0, 0, rmval-1);
  289.     }
  290.     else if (lu(buf,"m1")) {
  291.         set(&m1val, val, argtyp, 3, 0,
  292.             plval-m2val-m3val-m4val-1);
  293.     }
  294.     else if (lu(buf,"m2")) {
  295.         set(&m2val, val, argtyp, 2, 0,
  296.             plval-m1val-m3val-m4val-1);
  297.     }
  298.     else if (lu(buf,"m3")) {
  299.         set(&m3val, val, argtyp, 2, 0,
  300.             plval-m1val-m2val-m4val-1);
  301.         bottom = plval - m3val - m4val;
  302.     }
  303.     else if (lu(buf,"m4")) {
  304.         set(&m4val, val, argtyp, 3, 0,
  305.             plval-m1val-m2val-m3val-1);
  306.         bottom = plval - m3val - m4val;
  307.     }
  308.     else if (lu(buf,"eh")) {
  309.         gettl(buf, ehead, ehlim);
  310.     }
  311.     else if (lu(buf,"oh")) {
  312.         gettl(buf, ohead, ohlim);
  313.     }
  314.     else if (lu(buf,"ef")) {
  315.         gettl(buf, efoot, eflim);
  316.     }
  317.     else if (lu(buf,"of")) {
  318.         gettl(buf, ofoot, oflim);
  319.     }
  320.     else if (lu(buf,"cc")) {
  321.         /* change command character */
  322.         cchar = argtyp;
  323.         if (cchar == EOS || cchar == NEWLINE) {
  324.             cchar = '.';
  325.         }
  326.     }
  327.     else if (lu(buf,"ne")) {
  328.         if (lineno + val > bottom && lineno <= bottom){
  329.             space(val);
  330.             lineno = 0;
  331.         }
  332.     }
  333.     else if (lu(buf,"bs")) {
  334.         set(&bsval, val, argtyp, 1, 0, HUGE);
  335.     }
  336.     else if (lu(buf,"ju")) {
  337.         rjust = YES;
  338.     }
  339.     else if (lu(buf,"nj")) {
  340.         rjust = NO;
  341.     }
  342.     else if (lu(buf,"so")) {
  343.         /* start new source file */
  344.         if (getwrd(buf, &i, name) == 0) {
  345.             return;
  346.         }
  347.         if (level + 1 >= MAXOFILES) {
  348.             error("so commands nested too deeply.");
  349.         }
  350.         infile [level+1] = open(name, READ);
  351.         if (infile [level+1] != ERR) {
  352.             level++;
  353.         }
  354.     }
  355.     else if (lu(buf,"cu")) {
  356.         ulval = 0;
  357.         set(&cuval, val, argtyp, 0, 1, HUGE);
  358.     }
  359.     else if (lu(buf,"de")) {
  360.         dodef(buf, infile [level]);
  361.     }
  362.     else if (lu(buf,"nr")) {
  363.         /* set number register */
  364.         if (getwrd(buf, &i, name) == 0) {
  365.             return;
  366.         }
  367.         fold(name);
  368.         if (name [0] < 'a' || name[0] > 'z') {
  369.             error("invalid number register name.");
  370.         }
  371.         val = getval(buf, &i, &argtyp);
  372.         set(&nr [name[0]-'a'], val, argtyp,
  373.             0, -HUGE, HUGE);
  374.     }
  375.     else if (lu(buf,"st")) {
  376.         /* space to line n from top of page */
  377.         if (argtyp == '-') {
  378.             spval = plval;
  379.         }
  380.         else {
  381.             spval = 0;
  382.         }
  383.         set(&spval, val, argtyp, 0, 1, bottom);
  384.         if (spval > lineno && lineno == 0) {
  385.             phead();
  386.         }
  387.         if (spval > lineno) {
  388.             space(spval - lineno);
  389.         }
  390.     }
  391.     else {
  392.         /* ignore unknown commands */
  393.         return;
  394.     }
  395. }
  396.  
  397. /* return true if first two characters of buffer matches
  398.  * the string.
  399.  */
  400.  
  401. BOOL lu (buf, string) char *buf, *string;
  402. {
  403.     if ( buf [1] == string[0] &&
  404.          buf [2] == string[1]
  405.        ) {
  406.         return(YES);
  407.     }
  408.     else {
  409.         return(NO);
  410.     }
  411. }
  412.  
  413. /*  dodef - define a command; .de xx is in buf
  414.  *          read lines until a .en is found
  415.  */
  416.  
  417. dodef(buf, fd)
  418. char *buf;
  419. int fd;
  420. {
  421.     /* include cparam */
  422.     char name [MAXNAME], defn [MAXDEF];
  423.     int  i;
  424.  
  425.     /* comment out -----
  426.     printf("in dodef:  buf = %s\n", buf);
  427.     ----- end comment out */
  428.  
  429.     /* get name */
  430.     i = 0;
  431.     getwrd(buf, &i, name);
  432.     i = getwrd(buf, &i, name);
  433.  
  434.     /* comment out -----
  435.     printf("dodef:  name = %s\n", name);
  436.     ----- end comment out */
  437.  
  438.     if (i == 0) {
  439.         /* null definition -- ignore */
  440.         return;
  441.     }
  442.  
  443.     /* allow arbitrary length names */
  444.  
  445.     i = 0;
  446.     while (ngetln(buf, fd) != EOF) {
  447.         /* .en terminates macro definition */
  448.         if ( buf [0] == cchar &&
  449.              buf [1] == 'e' &&
  450.              buf [2] == 'n'
  451.            ) {
  452.             break;
  453.         }
  454.         addstr(buf, defn, &i, MAXDEF);
  455.     }
  456.  
  457.     if (addset(EOS, defn, &i, MAXDEF) == NO) {
  458.         error("definition too long.");
  459.     }
  460.     entdef(name, defn);
  461. }
  462.  
  463. /*  doesc - expand values of number regs into buf */
  464.  
  465. doesc(buf, tbuf, size)
  466. char *buf, *tbuf; int size;
  467. {
  468.     /* include cnr */
  469.     int  i, j;
  470.  
  471.     j = 0;    /*  expand into tbuf */
  472.     for (i = 0; buf [i] != EOS && j < size; i++) {
  473.         if (buf [i] != '@') {
  474.             tbuf [j++] = buf[i];
  475.         }
  476.         else if (buf [i+1] == '@') {
  477.             /* two at signs count as one */
  478.             tbuf [j++] = '@';
  479.             i++;
  480.         }
  481.         else if ( buf [i+1] == 'n' &&
  482.                   isalpha(buf [i+2])
  483.                 ) {
  484.             /* @na is request for number reg a */
  485.             j += itoc( nr [tolower(buf [i+2])-'a'],
  486.                        tbuf + j,
  487.                        size - j - 1
  488.                       );
  489.             i += 2;
  490.         }
  491.         else {
  492.             tbuf [j++] = buf[i];
  493.         }
  494.     }
  495.     tbuf [j] = EOS;
  496.     scopy(tbuf, 0, buf, 0);
  497. }
  498.  
  499. /*  doroff - format text in file fd */
  500.  
  501. doroff(fd)
  502. int  fd;
  503. {
  504.     /* include cfiles, cparam */
  505.     char inbuf [INSIZE];
  506.  
  507.     infile [0] = fd;
  508.     for (level = 0; level >= 0; level--) {
  509.         while (ngetln(inbuf, infile [level]) != EOF) {
  510.  
  511.             if (inbuf [0] == cchar) {
  512.                 command(inbuf);
  513.             }
  514.             else {
  515.                 text(inbuf);
  516.             }
  517.         }
  518.  
  519.         /* close an .so file */
  520.         if (level > 0 && infile [level] != ERR) {
  521.             close(infile [level]);
  522.         }
  523.     }
  524. }
  525.  
  526. /*  dotabs - expand tabs in buf */
  527.  
  528. dotabs(buf, tbuf, size)
  529. char *buf, *tbuf; int size;
  530. {
  531.     /* include cparam */
  532.     int  i, j;
  533.  
  534.     /* expand into tbuf */
  535.     j = 0;
  536.     for (i = 0; buf [i] != EOS && j < size; i++) {
  537.         if (buf [i] == TAB) {
  538.             while (j < size) {
  539.                 tbuf [j++] = ' ';
  540.                 if ( tabs [j] == YES ||
  541.                      j >= INSIZE
  542.                    ) {
  543.                     break;
  544.                 }
  545.             }
  546.         }
  547.         else {
  548.             tbuf [j++] = buf [i];
  549.         }
  550.     }
  551.     tbuf [j] = EOS;
  552.     scopy(tbuf, 0, buf, 0);
  553. }
  554.  
  555. /*  entdef - enter name and definition in macro table */
  556.  
  557. entdef (name, defn)
  558. char *name, *defn;
  559. {
  560.     /* include cmac */
  561.     int  i;
  562.     char *locn;
  563.  
  564.     /* comment out -----
  565.     printf("entdef:  name = %s, defn = \n%s\n",name,defn);
  566.     ----- end comment out */
  567.  
  568.     if ((locn = lookup (name, mactbl)) != 0) {
  569.         /* erase old definition */
  570.         delete(name, mactbl);
  571.     }
  572.     enter (name, defn, mactbl);
  573. }
  574.  
  575. /*  eval - evaluate defined command; push back definition.
  576.  *         buf contains a call to a macro.
  577.  *         defn contains its definition.
  578.  *         substitute args from buf into definition and
  579.  *         push it all back.
  580.  */
  581.  
  582. eval(buf, defn)
  583. char *buf, *defn;
  584. {
  585.     int  i, j, k;
  586.     int argptr [10];
  587.  
  588.     /* comment out -----
  589.     printf("eval:  buf = %s\ndefn = %s\n", buf, defn);
  590.     ----- end comment out */
  591.  
  592.     /* create null string */
  593.     buf [0] = EOS;
  594.  
  595.     /* initialize pointers to null string */
  596.     for (j = 0; j < 10; j++) {
  597.         argptr [j] = 0;
  598.     }
  599.  
  600.     /* up to 9 positional arguments are allowed.
  601.      * $0 refers to command name.
  602.      */
  603.     for (i= 1, j = 0; j < 10; j++) {
  604.  
  605.         /* scan past blanks ending previous argument */
  606.         skipbl(buf, &i);
  607.         if (buf [i] == NEWLINE || buf[i] == EOS) {
  608.             break;
  609.         }
  610.  
  611.         /* point argptr at arg */
  612.         argptr [j] = i;
  613.         while ( buf [i] != ' ' &&
  614.                 buf [i] != TAB &&
  615.             buf [i] != NEWLINE &&
  616.             buf [i] != EOS
  617.               ) {
  618.             i++;
  619.         }
  620.         /* end argument */
  621.         buf [i++] = EOS;
  622.  
  623.         /* comment out -----
  624.         printf("argptr[%d] = %d,",j, argptr[j]);
  625.         printf("buf + argptr[%d] = %s\n",
  626.             j, buf + argptr[j]);
  627.         ----- end comment out */
  628.     }
  629.  
  630.     /* push the defintion back in reverse order.
  631.      * substitute actual parameters for $1 ... $9
  632.      * substitute command name for $0
  633.      */
  634.     for (k = length(defn) - 1; k > 0; k--) {
  635.         if (defn [k-1] != ARGFLAG) {
  636.             putbak(defn [k]);
  637.         }
  638.         else {
  639.             if (defn [k] < '0' || defn [k] > '9') {
  640.                 putbak(defn [k]);
  641.             }
  642.             else {
  643.                 i = defn [k] - '0';
  644.                 pbstr(buf + argptr [i]);
  645.                 k--;    /*  skip over $ */
  646.             }
  647.         }
  648.     }
  649.     /* do last character */
  650.     if (k >= 0) {
  651.         putbak(defn [k]);
  652.     }
  653. }
  654. }
  655.  
  656.     /* push the defintion back in reverse order.
  657.      * substitute actual parameters for $1 ... $9
  658.      * substitute command name